package com.itheima.service.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.common.entity.PageResult;
import com.itheima.common.pojo.CheckGroup;
import com.itheima.common.pojo.Setmeal;
import com.itheima.common.pojo.dto.SetmealPageQueryDTO;
import com.itheima.mapper.CheckGroupMapper;
import com.itheima.mapper.SetmealMapper;
import com.itheima.service.SetmealService;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import java.io.FileWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SetmealServiceImpl implements SetmealService {

    private static final Logger log = LoggerFactory.getLogger(SetmealServiceImpl.class);

    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private CheckGroupMapper checkGroupMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    // 静态页面输出路径
    private static final String MOBILE_OUTPUT_PATH = "src/main/resources/static/pages/";
    
    private static final String UPLOAD_IMAGES_KEY = "upload:images";
    private static final String SETMEAL_IMAGES_KEY = "setmeal:images";

    /**
     * 新增套餐
     * @param setmeal
     * @param checkgroupIds
     */
    @Transactional(rollbackFor = Exception.class)
    public void save(Setmeal setmeal, String checkgroupIds) throws Exception {
        try {
            // 保存套餐基本信息
            setmealMapper.insert(setmeal);
            Integer setmealId = setmeal.getId();
            
            // 保存套餐和检查组关系
            if (checkgroupIds != null && !checkgroupIds.isEmpty()) {
                String[] checkGroupIdArray = checkgroupIds.split(",");
                for (String checkGroupId : checkGroupIdArray) {
                    //Integer.parseInt(checkGroupId.trim())用于将字符串形式的检查组ID转换为整数，并去除前后空格。
                    setmealMapper.insertSetmealAndCheckGroup(setmealId, Integer.parseInt(checkGroupId.trim()));
                }
            }
            
            // 从URL中提取图片名称并保存到Redis的套餐图片集合
            String imageUrl = setmeal.getImg();
            if (imageUrl != null && !imageUrl.isEmpty()) {
                String objectName = extractObjectNameFromUrl(imageUrl);
                redisTemplate.opsForSet().add(SETMEAL_IMAGES_KEY, objectName);
            }

            //生成静态页面
            generateMobileStaticPages();
        } catch (Exception e) {
            log.error("保存套餐失败：{}", e.getMessage());
            throw e;
        }
    }

    /**
     * 生成所有静态页面
     */
    private void generateMobileStaticPages() throws Exception {
        // 生成列表页
        generateSetmealListPage();
        // 生成详情页
        generateSetmealDetailPages();
    }

    /**
     * 生成套餐列表页面
     */
    private void generateSetmealListPage() throws Exception {
        // 获取所有套餐数据
        List<Setmeal> setmealList = setmealMapper.findAll();

        // 构造模板数据
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("setmealList", setmealList);

        // 生成静态页面
        Template template = freeMarkerConfigurer.getConfiguration()
                .getTemplate("mobile/setmeal_list.ftl");
        String outputFile = MOBILE_OUTPUT_PATH + "setmeal_list.html";
        try (Writer out = new FileWriter(outputFile)) {
            template.process(dataMap, out);
        }
    }

    /**
     * 生成套餐详情页面
     */
    private void generateSetmealDetailPages() throws Exception {
        List<Setmeal> setmealList = setmealMapper.findAll();
        for (Setmeal setmeal : setmealList) {
            // 获取完整的套餐信息(包含检查组)
            setmeal = setmealMapper.findById(setmeal.getId());

            // 构造模板数据
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("setmeal", setmeal);

            // 生成静态页面
            Template template = freeMarkerConfigurer.getConfiguration()
                    .getTemplate("mobile/setmeal_detail.ftl");
            String outputFile = MOBILE_OUTPUT_PATH + "setmeal_detail_" + setmeal.getId() + ".html";
            try (Writer out = new FileWriter(outputFile)) {
                template.process(dataMap, out);
            }
        }
    }

    private String extractObjectNameFromUrl(String imageUrl) {
        String urlWithoutProtocol = imageUrl.substring(imageUrl.indexOf("//") + 2);
        return urlWithoutProtocol.substring(urlWithoutProtocol.indexOf("/") + 1);
    }

    /**
     * 删除套餐
     * @param ids
     */
    @Transactional
    public void deleteBatch(List<Integer> ids) {
        ids.forEach(id -> {
            // 先删除套餐和检查组的关联关系
            setmealMapper.deleteSetmealCheckGroup(id);
            // 再删除套餐表中的数据
            setmealMapper.deleteById(id);
        });
    }

    /**
     * 修改套餐
     * @param setmeal
     */
    @Transactional
    public void update(Setmeal setmeal, String checkGroupIds) {
        //修改套餐表基本信息
        setmealMapper.update(setmeal);
        //修改套餐表的检查项信息
        //删除原有的检查项关联
        checkGroupMapper.deleteBySetmealId(setmeal.getId());
        //添加新的检查项关联
        if (checkGroupIds != null && !checkGroupIds.isEmpty()) {
            String[] checkGroupIdArray = checkGroupIds.split(",");
            for (String checkGroupId : checkGroupIdArray) {
                setmealMapper.insertSetmealAndCheckGroup(setmeal.getId(), Integer.parseInt(checkGroupId.trim()));
            }
        }
    }

    /**
     * 分页查询
     * @param setmealDTO
     * @return
     */
    public PageResult pageQuery(SetmealPageQueryDTO setmealDTO) {
        PageHelper.startPage(setmealDTO.getCurrentPage(), setmealDTO.getPageSize());
        Page<Setmeal> page = setmealMapper.pageQuery(setmealDTO);
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * 根据套餐id查询关联的检查组id
     * @param setmealId
     * @return
     */
    public List<Integer> findCheckGroupIdsBySetmealId(Integer setmealId) {
        return checkGroupMapper.findCheckGroupIdsBySetmealId(setmealId);
    }

    /**
     * 根据套餐id查询套餐信息
     * @param id
     * @return
     */
    public Setmeal findById(Integer id) {
        return setmealMapper.findById(id);
    }

}
